<?php

if(!defined('IN_DISCUZ')) {
	exit('Access Denied');
}
class OAuthClient{
	private $AppId = '';
	private $AppKey = '';
	private $URL = 'https://graph.qq.com/oauth2.0/';
	private $UserInfoURL = 'https://graph.qq.com/user/get_user_info';
	
	public function __construct($connectAppId = '', $connectAppKey = '', $apiIp = '') {
		global $_G;
		$this->AppId = $_G['setting']['connectappid'];
		$this->AppKey = $_G['setting']['connectappkey'];
		if(!$this->AppId || !$this->AppKey) {
			throw new Exception('connectAppId/connectAppKey Invalid', __LINE__);
		}
	}
	
	public function get_tokenCode_url($redirect_uri) {
		$params = array(
			'response_type' => 'code',
			'client_id' => $this->AppId,
			'state' => md5(FORMHASH),
			'scope' => 'get_user_info,add_share,add_t,add_pic_t,get_repost_list',
			'redirect_uri' => $redirect_uri,
		);
		return $this->URL.'authorize?'.$this->httpBuild($params);
	}
	
	public function get_token_openid($redirect_uri,$token_code) {
		global $_G;
		$params = array(
			'grant_type' => 'authorization_code',
			'client_id' => $this->AppId,
			'client_secret' => $this->AppKey,
			'code' => $token_code,
			'redirect_uri' => $redirect_uri
		);
		$response = dfsockopen($this->URL.'token?'.$this->httpBuild($params));
		
		parse_str($response, $result);
		if($result['access_token'] && $result['refresh_token']) {
			$response = $this->callback(dfsockopen($this->URL.'me?access_token='.$result['access_token']));
			if($response->openid) {
				$result = array(
					'openid' => $response->openid,
					'access_token' => $result['access_token']
				);
				return $result;
			}
		}
	}
	
	public function get_UserInfo($accessToken ,$openId) {
		$params = array(
			'access_token' => $accessToken,
			'oauth_consumer_key' => $this->AppId,
			'openid' => $openId,
		);
		$response = dfsockopen($this->UserInfoURL.'?'.$this->httpBuild($params));
		$data = json_decode($response,true);
		if(isset($data['ret']) && $data['ret'] == 0) {
			return $data;
		} else {
			throw new Exception('request failed', 999);
		}
	}
	
	public function connectMergeMember() {
		global $_G;
		static $merged;
		if($merged) {
			return;
		}

		$connect_member = C::t('#qqconnect#common_member_connect')->fetch($_G['uid']);
		if ($connect_member) {
			$_G['member'] = array_merge($_G['member'], $connect_member);
			$user_auth_fields = $connect_member['conisfeed'];
			if ($user_auth_fields == 0) {
				$_G['member']['is_user_info'] = 0;
				$_G['member']['is_feed'] = 0;
			} elseif ($user_auth_fields == 1) {
				$_G['member']['is_user_info'] = 1;
				$_G['member']['is_feed'] = 1;
			} elseif ($user_auth_fields == 2) {
				$_G['member']['is_user_info'] = 1;
				$_G['member']['is_feed'] = 0;
			} elseif ($user_auth_fields == 3) {
				$_G['member']['is_user_info'] = 0;
				$_G['member']['is_feed'] = 1;
			}
			unset($connect_member, $_G['member']['conisfeed']);
		}
		$merged = true;
	}
	
	public function callback($response) {
		if(strpos($response, "callback") === false) {
			return array();
		}
		$lpos = strpos($response, "(");
		$rpos = strrpos($response, ")");
		$response = substr($response, $lpos + 1, $rpos - $lpos - 1);
		return json_decode($response);
	}
	
	public function curl($url){
		$response = '';
		
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
		curl_setopt($ch, CURLOPT_URL, $url);
		$data = curl_exec($ch);
		$status = curl_getinfo($ch);
		$errno = curl_errno($ch);
		curl_close($ch);
		$response = array('status'=>$status,'data'=>$data,'errno'=>$errno);
		
		$response = dfsockopen($url.'?'.$utilService->httpBuildQuery($params, '', '&'));
		
		parse_str($response, $result);
		if($result['access_token'] && $result['refresh_token']) {
			$params = array(
				'access_token' => $result['access_token']
			);
			$response = $this->callback($this->dfsockopen($this->_openIdURL_V2.'?'.$utilService->httpBuildQuery($params, '', '&')));
			if($response->openid) {
				$result = array(
					'openid' => $response->openid,
					'access_token' => $result['access_token']
				);
				return $result;
			} else {
				$result->error = $result->error ? $result->error : self::RESPONSE_ERROR;
				throw new Exception($result->error, __LINE__);
			}
		} else {
			$result = $this->callback($response);
			$result->error = $result->error ? $result->error : self::RESPONSE_ERROR;
			throw new Exception($result->error, __LINE__);
		}
		
		
		//-------请求为空
		if(empty($response)){
		return ;
		}
		
		return $response;
	}
	
	public function httpBuild($data){

		$render = array();
		if (empty($arg_separator)) {
			$arg_separator = @ini_get('arg_separator.output');
			empty($arg_separator) && $arg_separator = '&';
		}
		foreach ((array) $data as $key => $val) {
			if (is_array($val) || is_object($val)) {
				$_key = empty($prefix) ? "{$key}[%s]" : sprintf($prefix, $key) . "[%s]";
				$_render = $this->httpBuildQuery($val, '', $arg_separator, $_key);
				if (!empty($_render)) {
					$render[] = $_render;
				}
			} else {
				if (is_numeric($key) && empty($prefix)) {
					$render[] = urlencode("{$numeric_prefix}{$key}") . "=" . urlencode($val);
				} else {
					if (!empty($prefix)) {
						$_key = sprintf($prefix, $key);
						$render[] = urlencode($_key) . "=" . urlencode($val);
					} else {
						$render[] = urlencode($key) . "=" . urlencode($val);
					}
				}
			}
		}
		$render = implode($arg_separator, $render);
		if (empty($render)) {
			$render = '';
		}

		return $render;
	}
	
	public function redirect($url, $code = 302) {

		@ob_end_clean();
		@ob_start();

		$errorChars = array();
		for ($i = 0; $i <= 31; $i ++) {
			$errorChars[] = chr($i);
		}

		$url = trim(str_replace($errorChars, '', $url));

		if (strpos($url, '/') === 0) {
			$url = '/' . ltrim($url, '/');
		}

		@header('Location: ' . $url, true, $code);

		exit;
	}
}

?>